Java: add experimental java/ldap-dn-injection-library-mode query#22003
Open
tonghuaroot wants to merge 1 commit into
Open
Java: add experimental java/ldap-dn-injection-library-mode query#22003tonghuaroot wants to merge 1 commit into
tonghuaroot wants to merge 1 commit into
Conversation
The supported java/ldap-injection query starts from remote flow sources, so it does not report on authentication frameworks, where the login principal arrives as a method parameter rather than at a servlet parameter or similar. This experimental query detects LDAP distinguished-name injection (CWE-90, RFC 2253) into a bind DN inside such a framework. Sources are library-boundary values: login-principal accessors of common auth frameworks (Apache Shiro AuthenticationToken, Spring Security Authentication, java.security.Principal) and the string parameters of DN-builder-shaped methods. The DN-builder source model is name-heuristic, a deliberate precision/recall trade for the library case where there is no remote flow source to anchor on; the query is therefore experimental and medium precision. Sinks are the bind-DN positions: javax.naming Context / DirContext bind, rebind, lookup, lookupLink, createSubcontext; the java.naming.security.principal environment value; and Apache Shiro LdapContextFactory.getLdapContext. Barriers are RFC 2253 DN escapers such as Rdn.escapeValue. Anchored on Apache Shiro CVE-2026-49268. Adds a qhelp, a true-positive/true-negative test, and the Shiro stubs the test needs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A new experimental query,
java/ldap-dn-injection-library-mode, that detects LDAPdistinguished-name injection (CWE-90, RFC 2253) into a bind DN inside an
authentication library or framework (Apache Shiro, a custom Spring Security realm,
a CAS / pac4j SPI, a Keycloak provider).
Why the supported query misses this
java/ldap-injectionstarts fromActiveThreatModelSource(remote flow sources). Anauth framework has none — the login principal arrives as a method parameter, not
as a servlet parameter or request body. On a framework database the supported query
therefore has zero sources, regardless of the sink model. This query closes that
source-boundary gap with library-boundary sources.
Sources (library-boundary)
AuthenticationToken.getPrincipal/getUsername, Spring SecurityAuthentication.getName/getPrincipal,java.security.Principal.getName.Stringparameter of a method whose name lookslike a DN builder (
getUserDn,*UserDn,buildDn,resolveDn,getUsernameWithSuffix,get*Principal, ...).Honest caveat — the DN-builder source model is name-heuristic. It keys partly off
method names. This is a deliberate precision/recall trade for the library case where
there is no remote flow source to anchor on: a framework that builds the DN in a
differently named helper is missed, and a benign method that matches the name pattern
may produce a false positive. This is why the query is
experimentaland@precision medium, and the trade-off is documented in both the QLDoc and the qhelp.Triage a result by confirming the value reaches a real bind sink unescaped.
Sinks (bind DN)
javax.namingContext/DirContextbind/rebind/lookup/lookupLink/createSubcontext(theString nameargument); thejava.naming.security.principalenvironment value; and Shiro
LdapContextFactory.getLdapContext(theprincipalargument).
new LdapName(String)is deliberately excluded (it commonly parses anexisting cert/principal DN, not a fresh one for a bind). Barriers are RFC 2253 DN
escapers (
Rdn.escapeValue, SpringLdapEncoder.nameEncode, ESAPIencodeForDN).The query defines its sinks inline rather than reusing the supported
LdapInjectionSinklibrary, so it stands alone and does not depend on the companionbind-DN-sinks PR being merged first.
Evidence (Apache Shiro CVE-2026-49268)
CVE-2026-49268 (fixed 2.2.1 / 3.0.0-alpha-2). Built a database from
apache/shiro@shiro-root-2.2.0and ran a 3-way comparison:java/ldap-injectionjava/ldap-injection+ bind-DN sinks (companion PR)java/ldap-dn-injection-library-mode(this PR)The 8 results land on exactly the patched code:
DefaultLdapRealm.getUserDn/getLdapContext(principal, ...)andActiveDirectoryRealm.getUsernameWithSuffix, withthe source correctly traced to
AuthenticationToken.getUsername()/getPrincipal().This satisfies the experimental-query requirement of at least one true positive on a
real project.
Tests / help
Ships a qhelp (with bad/good samples) and a true-positive / true-negative test shaped
like the Shiro realm (
getUserDnconcatenation vsRdn.escapeValue), plus the Shirostubs the test needs.
codeql test runis green and the query compiles with--warnings=error.